package xyz.penghaonan.adtools;

import static com.facebook.ads.AdSettings.IntegrationErrorMode.INTEGRATION_ERROR_CRASH_DEBUG_MODE;

import android.content.Context;
import android.text.TextUtils;
import android.view.View;

import androidx.annotation.NonNull;

import com.facebook.ads.Ad;
import com.facebook.ads.AdSettings;
import com.google.android.gms.ads.MobileAds;
import com.google.android.gms.ads.initialization.InitializationStatus;
import com.google.android.gms.ads.initialization.OnInitializationCompleteListener;
import com.penghaonan.appframework.AppDelegate;
import com.penghaonan.appframework.utils.CollectionUtils;
import com.penghaonan.appframework.utils.threadpool.IOThreadPool;
import com.penghaonan.appframework.utils.threadpool.ThreadPoolTask;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import xyz.penghaonan.adtools.manager.AdConfig;
import xyz.penghaonan.adtools.manager.AdSpotInfo;
import xyz.penghaonan.adtools.manager.AdViewLoader;

public final class ADTools {

    private static AdViewLoader adLoader;
    private static IOThreadPool threadPool;

    private static boolean enable = true;
    private static boolean debug = false;
    private static AdConfig adConfig;
    private static boolean inited;

    private static final Map<String, ThreadPoolTask> requestTaskMap = new ConcurrentHashMap<>();

    public static class AdLoadResult {
        public View adView;
        public AdSpotInfo.AdInfo type;
        public String failMsg;
    }

    public static void init(AdConfig adConfig) {
        if (adConfig == null) {
            return;
        }
        ADTools.adConfig = adConfig;
        ADLog.i("inited");
        MobileAds.initialize(AppDelegate.getApp(), new OnInitializationCompleteListener() {
            @Override
            public void onInitializationComplete(@NonNull InitializationStatus initializationStatus) {
                ADLog.i("MobileAds onInitializationComplete");
            }
        });

        adLoader = new AdViewLoader();
        threadPool = new IOThreadPool();
        inited = true;
    }

    public static void setEnable(boolean enable) {
        ADTools.enable = enable;
        ADLog.i("setEnable:" + enable);
    }

    public static boolean isEnable() {
        return enable;
    }

    public static void setDebug(boolean debug) {
        ADTools.debug = debug;
        if (debug) {
            AdSettings.setIntegrationErrorMode(INTEGRATION_ERROR_CRASH_DEBUG_MODE);
        }
    }

    public static AdConfig getAdConfig() {
        return adConfig;
    }

    public interface AdViewCallback {
        void onAdViewCallback(View adView);

        void onAdViewLoadFailed(String msg);
    }

    public static AdSpotInfo findSpotInfo(String spotId) {
        if (adConfig == null) {
            return null;
        }
        if (CollectionUtils.isEmpty(adConfig.ad_spots)) {
            return null;
        }
        for (AdSpotInfo adSpotInfo : adConfig.ad_spots) {
            if (TextUtils.equals(adSpotInfo.spotId, spotId)) {
                return adSpotInfo;
            }
        }
        return null;
    }

    public static void cancelRequest(@NonNull String spotId) {
        ThreadPoolTask task = requestTaskMap.get(spotId);
        threadPool.cancel(task);
    }

    public static void requestAdBanner(@NonNull Context context, @NonNull String spotId, @NonNull AdViewCallback callback) {

        AdViewCallback innerCallback = new AdViewCallback() {
            @Override
            public void onAdViewCallback(View adView) {
                callback.onAdViewCallback(adView);
            }

            @Override
            public void onAdViewLoadFailed(String msg) {
                callback.onAdViewLoadFailed(msg);
            }
        };

        ADLog.i("requestAdBanner:" + spotId);
        if (!inited) {
            ADLog.i("requestAdBanner: inited:" + inited);
            return;
        }
        if (requestTaskMap.containsKey(spotId)) {
            ADLog.i("requestAdBanner: has requesting task");
            callback.onAdViewLoadFailed("Spot is requesting");
            return;
        }
        AdSpotInfo spotInfo = findSpotInfo(spotId);
        if (spotInfo == null) {
            ADLog.i("requestAdBanner: no spot info");
            callback.onAdViewLoadFailed("No spot info");
            return;
        }
        ThreadPoolTask task = new ThreadPoolTask() {
            @Override
            protected void doInBackground() {
                AdLoadResult result = adLoader.loadAdView(context, spotInfo);
                requestTaskMap.remove(spotId);
                AppDelegate.post(new Runnable() {
                    @Override
                    public void run() {
                        if (result.adView == null) {
                            callback.onAdViewLoadFailed(result.failMsg);
                        } else {
                            callback.onAdViewCallback(result.adView);
                        }
                    }
                });
            }
        };
        threadPool.addTask(task);
        requestTaskMap.put(spotId, task);
    }
}
